#pragma once

#include <iostream>
#include <string>
#include <unordered_map>
#include <functional>

using std::cout;
using std::endl;
using std::string;
using std::to_string;
using std::unordered_map;
using std::function;

template<class T>
class TaskCalc
{
public:
    TaskCalc()
    {}
    
    TaskCalc(const T& x = T(), const T& y = T(), const char& op = '+')
        :_x(x)
        ,_y(y)
        ,_result(0)
        ,_err(0)
        ,_op(op)
    {}

    //根据运算数和运算符计算出结果
    void operator()()
    {
        unordered_map<char, function<void(void)>> hash{
            {'+', [&](){ _result = _x + _y; }},
            {'-', [&](){ _result = _x - _y; }},
            {'*', [&](){ _result = _x * _y; }},
            {'/', [&](){
                if(_y == T()) _err = 1;
                else _result = _x / _y;
            }},
            {'%', [&](){
                if(_y == T()) _err = 1;
                else  _result = _x % _y;    //double 类型无法进行模运算，编译会直接报错
            }}
        };

        hash[_op]();  //调用运算式
    }

    //打印基本信息
    string formatArgs()
    {
        return to_string(_x) + " " + _op + " " + to_string(_y) + " = ?";
    }

    //打印运算结果
    string formatResult()
    {
        return to_string(_x) + " " + _op + " " + to_string(_y) + " = " + to_string(_result) + "(" + to_string(_err) + ")";
    }

private:
    T _x;
    T _y;
    T _result;  //运算结果
    int _err;   //错误码
    char _op;   //运算符
};